/**
 * 
 */
package com.pmsco.pms.business;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.pmsco.pms.business.dto.PmsMenuRequestDTO;
import com.pmsco.pms.business.dto.PmsMenuReturnDTO;
import com.pmsco.pms.core.constant.PmsConstant;
import com.pmsco.pms.core.domain.PmsMenu;
import com.pmsco.pms.core.domain.PmsMenuRole;
import com.pmsco.pms.core.domain.PmsMenuStructure;
import com.pmsco.pms.core.domain.PmsRole;
import com.pmsco.pms.services.impl.PmsMenuRoleServiceImpl;
import com.pmsco.pms.services.impl.PmsMenuServiceImpl;
import com.pmsco.pms.services.impl.PmsMenuStructureServiceImpl;
import com.pmsco.pms.services.impl.PmsRoleServiceImpl;
import com.pmsco.pms.util.PmsMenuComparable;

/**
 * @author Long Tran
 *
 */
public class PmsMenuBusiness {
	private static final Logger logger = LoggerFactory.getLogger(PmsMenuBusiness.class);
	private PmsMenuRoleServiceImpl pmsMenuRoleService = new PmsMenuRoleServiceImpl();
	private PmsMenuServiceImpl pmsMenuService = new PmsMenuServiceImpl();
	private PmsRoleServiceImpl pmsRoleService = new PmsRoleServiceImpl();
	private PmsMenuStructureServiceImpl pmsMenuStructureService = new PmsMenuStructureServiceImpl();
	
	public PmsMenuReturnDTO listMenuData(PmsMenuRequestDTO pmsMenuRequestDTO) {
		logger.info("Start listMenuData");
		PmsMenuReturnDTO pmsMenuReturnDTO = new PmsMenuReturnDTO();
		
		List<PmsMenu> menulist = pmsMenuService.listPmsMenu(pmsMenuRequestDTO.getSearchField(), 
				pmsMenuRequestDTO.getSearchString(), 
				pmsMenuRequestDTO.getSearchOper(), 
				pmsMenuRequestDTO.getSidx(), 
				pmsMenuRequestDTO.getSord(), 
				pmsMenuRequestDTO.getPage(), 
				pmsMenuRequestDTO.getRows());
		
		Integer menulistSize = pmsMenuService.countListPmsMenu(pmsMenuRequestDTO.getSearchField(), 
				pmsMenuRequestDTO.getSearchString(), 
				pmsMenuRequestDTO.getSearchOper());
		
		pmsMenuReturnDTO.setMenulist(menulist);
		pmsMenuReturnDTO.setMenulistSize(menulistSize);
		
		logger.info("End listMenuData");
		return pmsMenuReturnDTO;
	}
	
	public PmsMenuReturnDTO editMenu(PmsMenuRequestDTO pmsMenuRequestDTO) {
		logger.info("Start editMenu");
		PmsMenuReturnDTO pmsMenuReturnDTO = new PmsMenuReturnDTO();
		
		pmsMenuReturnDTO.setPmsMenu(pmsMenuService.getMenuByName(pmsMenuRequestDTO.getMenuName()));
		pmsMenuReturnDTO.setMenulist(pmsMenuService.listPmsMenu(new PmsMenu()));
		pmsMenuReturnDTO.setRolelist(pmsRoleService.listPmsRole(new PmsRole()));
		pmsMenuReturnDTO.setMenuRoleList(pmsMenuRoleService.loadPmsMenuRoleByMenuId(pmsMenuReturnDTO.getPmsMenu().getId()));
		pmsMenuReturnDTO.setReturnView(PmsConstant.editMenu_View);
		
		logger.info("End editMenu");
		return pmsMenuReturnDTO;
	}
	
	public PmsMenuReturnDTO getTopMenuList(PmsMenuRequestDTO pmsMenuRequestDTO) {
		logger.info("Start getMenuList");
		PmsMenuReturnDTO pmsMenuReturnDTO = new PmsMenuReturnDTO();
		
		ArrayList<PmsMenu> menuList = new ArrayList<PmsMenu>();
		PmsMenu searchTemplate = new PmsMenu();
		if(pmsMenuRequestDTO.getPmsRole() == null) {
			searchTemplate.setIsLogonRequired(PmsConstant.unRequiredLogon);
		}
		searchTemplate.setIsTopLevel(PmsConstant.topMenuLevel);
		menuList.addAll(pmsMenuService.listPmsMenu(searchTemplate));
		Collections.sort(menuList, new PmsMenuComparable());
		pmsMenuReturnDTO.setMenulist(menuList);
		
		logger.info("End getMenuList");
		return pmsMenuReturnDTO;
	}
	
	public boolean isMenuEnableForRole(PmsMenu menu, Long roleId) {
		boolean ret = false;
		if(PmsConstant.unRequiredLogon.equals(menu.getIsLogonRequired()))
			return true;
		List<PmsMenuRole> menuRoles = pmsMenuRoleService.loadPmsMenuRoleByMenuId(menu.getId());
		if(menuRoles != null) {
			for(PmsMenuRole menuRole : menuRoles) {
				PmsRole role = menuRole.getRole();
				if(role.getId().compareTo(roleId) == 0) {
					ret = true;
				}
			}
		}
		return ret;
	}
	
	public PmsMenuReturnDTO createMenu(PmsMenuRequestDTO pmsMenuRequestDTO) {
		logger.info("Start createMenu");
		PmsMenuReturnDTO pmsMenuReturnDTO = new PmsMenuReturnDTO();
		
		pmsMenuReturnDTO.setPmsMenu(new PmsMenu());
		pmsMenuReturnDTO.setMenulist(pmsMenuService.listPmsMenu(new PmsMenu()));
		pmsMenuReturnDTO.setRolelist(pmsRoleService.listPmsRole(new PmsRole()));
		pmsMenuReturnDTO.setMenuRoleList(new ArrayList<PmsMenuRole>());
		pmsMenuReturnDTO.setReturnView(PmsConstant.createMenu_View);
		
		logger.info("End createMenu");
		return pmsMenuReturnDTO;
	}
	
	public PmsMenuReturnDTO saveMenu(PmsMenuRequestDTO pmsMenuRequestDTO) {
		logger.info("Start saveMenu");
		PmsMenuReturnDTO pmsMenuReturnDTO = new PmsMenuReturnDTO();
		
		logger.debug("Check if menu name existed");
		PmsMenu menuDetail = pmsMenuRequestDTO.getPmsMenu();
		PmsMenu existedMenu = pmsMenuService.getMenuByName(menuDetail.getName());
		
		logger.debug("Menu name: " + menuDetail.getName());
		logger.debug("Id: " + String.valueOf(menuDetail.getId()));
		if((existedMenu != null && menuDetail.getId() == null) || (existedMenu != null && existedMenu.getId().compareTo(menuDetail.getId()) != 0)) {
			pmsMenuReturnDTO.setReturnView(PmsConstant.editMenu_View);
			if(pmsMenuRequestDTO.getOldParentId() != null) {
				PmsMenu oldParent = pmsMenuService.getMenuById(pmsMenuRequestDTO.getOldParentId());
				menuDetail.setParent(oldParent);
			}
			pmsMenuReturnDTO.setPmsMenu(menuDetail);
			pmsMenuReturnDTO.setMenulist(pmsMenuService.listPmsMenu(new PmsMenu()));
			pmsMenuReturnDTO.setRolelist(pmsRoleService.listPmsRole(new PmsRole()));
			if(menuDetail.getId() == null) {
				pmsMenuReturnDTO.setMenuRoleList(new ArrayList<PmsMenuRole>());
			} else {
				pmsMenuReturnDTO.setMenuRoleList(pmsMenuRoleService.loadPmsMenuRoleByMenuId(pmsMenuReturnDTO.getPmsMenu().getId()));
			}
			pmsMenuReturnDTO.setErrorMessage(PmsConstant.menuName_Existed_Key);
		} else {
			if(existedMenu != null && existedMenu.getId().compareTo(menuDetail.getId()) == 0)
				menuDetail.setChildren(existedMenu.getChildren());
			pmsMenuService.saveOrUpdatePmsMenu(menuDetail);
			PmsMenu updatedMenu = pmsMenuService.getMenuByName(menuDetail.getName());

			if(pmsMenuRequestDTO.getParentId() != null) {
				updatedMenu.setOrderId(new Long(0));
				
				PmsMenuStructure pmsMenuStructure = null;
				if(pmsMenuRequestDTO.getOldParentId() != null) {
					pmsMenuStructure = pmsMenuStructureService.getPmsMenuStructure(pmsMenuRequestDTO.getOldParentId(), updatedMenu.getId());
				}
			
				if(pmsMenuStructure == null) {
					pmsMenuStructure = new PmsMenuStructure();
				}
				pmsMenuStructure.setChildMenuId(updatedMenu.getId());
				pmsMenuStructure.setParentMenuId(pmsMenuRequestDTO.getParentId());
				pmsMenuStructure.setOrderId(pmsMenuRequestDTO.getOrderId());
				pmsMenuStructureService.saveOrUpdatePmsMenuStructure(pmsMenuStructure);
			} else {
				if(pmsMenuRequestDTO.getOldParentId() != null) {
					pmsMenuStructureService.deletePmsMenuStructure(pmsMenuRequestDTO.getOldParentId(), updatedMenu.getId());
				}
			}			
			
			logger.debug("Start saving menu enable for role");
			String[] enableMenuIds = pmsMenuRequestDTO.getEnableMenuIds();
			ArrayList<Long> enableMenuArrayId = new ArrayList<Long>();
			for(int i = 0; i < enableMenuIds.length; i++) {
				String temp = enableMenuIds[i];
				if(!temp.isEmpty())
					enableMenuArrayId.add(Long.valueOf(enableMenuIds[i]));
			}
			
			ArrayList<Long> existedMenuArrayId = new ArrayList<Long>();
			List<PmsMenuRole> enableMenuRoles = pmsMenuRoleService.loadPmsMenuRoleByMenuId(updatedMenu.getId());
			logger.debug("Delete any menu role item does not contain in enableMenuArrayId");
			for(PmsMenuRole pmsMenuRole : enableMenuRoles) {
				if(!enableMenuArrayId.contains(pmsMenuRole.getId())) {
					pmsMenuRoleService.deletePmsMenuRole(pmsMenuRole);
				} else {
					existedMenuArrayId.add(pmsMenuRole.getId());
				}
			}
			
			logger.debug("Add new menu role if does not contain in existedMenuArrayId");
			for(Long enableMenuId : enableMenuArrayId) {
				if(!existedMenuArrayId.contains(enableMenuId)) {
					PmsMenuRole pmsMenuRole = new PmsMenuRole();
					pmsMenuRole.setMenu(updatedMenu);
					pmsMenuRole.setRole(pmsRoleService.getRoleById(enableMenuId));
					pmsMenuRoleService.saveOrUpdatePmsMenuRole(pmsMenuRole);
				}
			}
			
			pmsMenuReturnDTO.setReturnUrl(PmsConstant.listMenu_JspUrl);
		}
		
		logger.info("End saveMenu");
		return pmsMenuReturnDTO;
	}
	
	public void deleteMenus(String deleteMenuNames) {
		logger.info("Start deleteMenus");
		if(deleteMenuNames != null && !deleteMenuNames.isEmpty()) {
			String[] menuNames = deleteMenuNames.split(",");
			for(int i = 0; i < menuNames.length; i++) {
				String name = menuNames[i];
				PmsMenu menu = pmsMenuService.getMenuByName(name);
				
				logger.debug("Delete all menu structure");
				List<PmsMenu> children = menu.getChildren();
				for(PmsMenu child : children) {
					pmsMenuStructureService.deletePmsMenuStructure(menu.getId(), child.getId());
				}
				
				logger.debug("Delete all menu role");
				List<PmsMenuRole> menuRoles = pmsMenuRoleService.loadPmsMenuRoleByMenuId(menu.getId());
				for(PmsMenuRole menuRole : menuRoles) {
					pmsMenuRoleService.deletePmsMenuRole(menuRole);
				}
				
				logger.debug("Delete menu");
				pmsMenuService.deleteMenu(menu);
			}
		}
		logger.info("End deleteMenu");
	}
}
